<?php


/**
 * @notes moarkService
 * GiteeAI应用市场服务类
 * 
 * 提供与GiteeAI应用市场交互的各种功能，包括：
 * 1. 认证相关
 *    - createTemporaryToken: 创建临时的Access Token
 *    - sendVerificationCode: 发送验证码
 *    - getUserToken: 获取用户访问凭证
 *    - setUserToken: 设置用户访问令牌
 * 
 * 2. 应用信息
 *    - getAppInfo: 获取应用基本信息
 * 
 * 3. 用户信息
 *    - getCurrentUser: 获取当前用户信息
 * 
 * 4. 支付相关
 *    - createPayment: 创建支付订单
 *    - getPaymentDetail: 获取支付详情
 * 
 * 注意：
 * - 部分接口需要使用用户访问令牌进行鉴权
 * - 用户令牌可通过setUserToken方法设置
 * - 默认使用应用令牌进行鉴权
 */

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Cookie\CookieJar;
/**
 * @notes 发送POST请求
 * @param string $url 请求的URL
 * @param array $data POST数据
 * @param array $headers 请求头
 * @return array 包含响应状态码、响应体、响应头和错误信息的数组
 * @author 铂金小猪
 * @date 2025/2/24 11:20
 */
function send_post(string $url, array $data = [], array $headers = []): array {
    // 创建一个空的 CookieJar 实例
    $cookieJar = new CookieJar();

    // 创建客户端，并启用 Cookie 管理
    $client = new Client([
        'cookies' => $cookieJar,
    ]);
    try {
        $response = $client->request('POST', $url, [
            'json' => $data,
            'headers' => $headers,
        ]);

        $statusCode = $response->getStatusCode();
        $body = $response->getBody()->getContents();
        $responseHeaders = $response->getHeaders();
        $allCookies = iterator_to_array($cookieJar->getIterator());
        if ($statusCode == 200) {
            $body = json_decode($body, true);
        }

        return [
            'status_code' => $statusCode,
            'body' => $body,
            'headers' => $responseHeaders,
            'error' => null,
        ];
    } catch (RequestException $e) {
        $statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : 0;
        $body = $e->getResponse() ? $e->getResponse()->getBody()->getContents() : '';
        $responseHeaders = $e->getResponse() ? $e->getResponse()->getHeaders() : [];
        $error = $e->getMessage();

        return [
            'status_code' => $statusCode,
            'body' => $body,
            'headers' => $responseHeaders,
            'error' => $error,
        ];
    }
}

/**
 * @notes 发送GET请求
 * @param string $url 请求的URL
 * @param array $data 查询参数数组
 * @param array $headers 请求头
 * @return array 包含响应状态码、响应体、响应头和错误信息的数组
 * @author 铂金小猪
 * @date 2025/2/24 11:20
 */
function send_get(string $url, array $data = [], array $headers = []): array {
    $client = new Client();
    try {
        $response = $client->request('GET', $url, [
            'query' => $data,
            'headers' => $headers,
        ]);

        $statusCode = $response->getStatusCode();
        $body = $response->getBody()->getContents();
        $responseHeaders = $response->getHeaders();
        if ($statusCode == 200) {
            $body = json_decode($body, true);
        }
        return [
            'status_code' => $statusCode,
            'body' => $body,
            'headers' => $responseHeaders,
        ];
    } catch (RequestException $e) {
        $statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : 0;
        $body = $e->getResponse() ? $e->getResponse()->getBody()->getContents() : '';
        $responseHeaders = $e->getResponse() ? $e->getResponse()->getHeaders() : [];
        $error = $e->getMessage();
        return [
            'status_code' => $statusCode,
            'body' => $body,
            'headers' => $responseHeaders,
        ];
    }
}

class moarkService {
    private $appid = '';
    private $token = '';//开发者令牌
    private $userToken = ''; // 用户访问令牌
    private $data = [];

    public function __construct() {
        $this->data = [
            'appid' => $this->appid,
        ];
    }

    /**
     * 设置用户访问令牌
     * @param string $token 用户访问令牌
     * @return void
     */
    public function setUserToken($token) {
        $this->userToken = $token;
    }

    /**
     * GiteeApp发送POST请求
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param bool $useUserToken 是否使用用户令牌
     * @return array|false 请求结果
     */
    public function post($url, $data, $useUserToken = false) {
        $headers = [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer ' . ($useUserToken ? $this->userToken : $this->token)
        ];
        $data = array_merge($this->data, $data);    
        $result = send_post(
            'https://ai.gitee.com/v1/app/'.$url,
            $data,
            $headers   
        );
        return $result;
    }

    /**
     * GiteeApp发送GET请求
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param bool $useUserToken 是否使用用户令牌
     * @return array|false 请求结果
     */
    public function get($url, $data = [], $useUserToken = false) {
        $headers = [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer ' . ($useUserToken ? $this->userToken : $this->token)
        ];
        $result = send_get(
            'https://ai.gitee.com/v1/app/'.$url,
            $data,
            $headers
        );
        return $result;
    }

    /**
     * 创建临时的 Access Token
     * @param int $seconds 临时Token的有效时间，单位秒，范围5-3600
     * @return array|false 返回token和expired_at
     */
    public function createTemporaryToken($seconds = 3600) {
        return $this->post('tokens/temporary', [
            'seconds' => $seconds
        ]);
    }

    /**
     * 获取应用基本信息
     * @param string $appid 应用ID，用于唯一标识应用
     * @return array|false 返回应用的基本信息及收费计划信息
     */
    public function getAppInfo($appid) {
        return $this->get('', ['appid' => $appid]);
    }

    /**
     * 发送验证码
     * @param array $config 配置数组
     * @param string $config['appid'] 应用ID
     * @param string $config['mobile'] 手机号
     * @param string $config['email'] 邮箱
     * @param string $config['channel_type'] 验证码发送渠道，可选值：sms/email，默认sms
     * @return bool 验证码发送结果
     */
    public function sendVerificationCode($config) {
        $defaultConfig = [
            'channel_type' => 'sms',
            'mobile' => '',
            'email' => ''
        ];
        $config = array_merge($defaultConfig, $config);
        
        return $this->post('auth/vcode', [
            'appid' => $config['appid'],
            'mobile' => $config['mobile'],
            'email' => $config['email'],
            'channel_type' => $config['channel_type']
        ]);
    }

   
    /**
     * 获取用户访问凭证
     * @param array $config 配置数组
     * @param string $config['appid'] 应用ID
     * @param string $config['code'] 验证码
     * @param string $config['channel_type'] 验证码发送渠道，可选值：sms/email，默认sms
     * @param string $config['mobile'] 手机号
     * @param string $config['email'] 邮箱
     * @return array|false 返回用户访问令牌
     */
    public function getUserToken($config) {
        $defaultConfig = [
            'channel_type' => 'sms',
            'mobile' => '',
            'email' => ''
        ];
        $config = array_merge($defaultConfig, $config);
        
        $result = $this->post('auth/token', [
            'appid' => $config['appid'],
            'channel_type' => $config['channel_type'],
            'mobile' => $config['mobile'],
            'email' => $config['email'],
            'code' => $config['code']
        ]);

        if ($result && isset($result['access_token'])) {
            $this->setUserToken($result['access_token']);
        }

        return $result;
    }


    /**
     * 获取当前用户信息
     * @return array|false 返回用户信息及用户的订阅信息
     */
    public function getCurrentUser() {
        return $this->get('user', [], true);
    }

    /**
     * 创建支付订单
     * @param string $plan_ident 应用的收费计划标识符
     * @param int $quantity 购买数量，默认为1
     * @param string $type 支付方式，可选值：wepay/alipay
     * @return array|false 返回支付信息，包含支付跳转地址
     */
    public function createPayment($plan_ident, $quantity = 1, $type = 'wepay') {
        return $this->post('pay', [
            'plan_ident' => $plan_ident,
            'quantity' => $quantity,
            'type' => $type
        ], true);
    }

    /**
     * 获取支付详情
     * @param string $ident 支付号
     * @return array|false 返回支付详情
     */
    public function getPaymentDetail($ident) {
        return $this->get('pay', ['ident' => $ident], true);
    }
}
